/**********************************************************************
* Filename: CalendarDate.java
* Created: 2012/04/23
* @author Fernando Brito e Abreu
**********************************************************************/
package org.quasar.copaPaises.businessLayer;

import java.util.Set;
import java.util.HashSet;

public class CalendarDate
{
	public static Set<CalendarDate> allInstances = new HashSet<CalendarDate>();
	
	private int day;
	private int month;
	private int year;
	
	/**********************************************************************
	* Default constructor
	**********************************************************************/
	public CalendarDate()
	{
		allInstances.add(this);
	}
	
	/**********************************************************************
	* Parameterized constructor
	* @param day the day to initialize
	* @param month the month to initialize
	* @param year the year to initialize
	**********************************************************************/
	public CalendarDate(int day, int month, int year)
	{
		this.day = day;
		this.month = month;
		this.year = year;
		allInstances.add(this);
	}
	
	/**********************************************************************
	* Standard attribute getter
	* @return the day of the calendarDate
	**********************************************************************/
	public int day()
	{
		return day;
	}
	
	/**********************************************************************
	* Standard attribute setter
	* @param day the day to set
	**********************************************************************/
	public void setDay(int day)
	{
		this.day = day;
	}
	
	/**********************************************************************
	* Standard attribute getter
	* @return the month of the calendarDate
	**********************************************************************/
	public int month()
	{
		return month;
	}
	
	/**********************************************************************
	* Standard attribute setter
	* @param month the month to set
	**********************************************************************/
	public void setMonth(int month)
	{
		this.month = month;
	}
	
	/**********************************************************************
	* Standard attribute getter
	* @return the year of the calendarDate
	**********************************************************************/
	public int year()
	{
		return year;
	}
	
	/**********************************************************************
	* Standard attribute setter
	* @param year the year to set
	**********************************************************************/
	public void setYear(int year)
	{
		this.year = year;
	}
	
	/**********************************************************************
	* User-defined operation specified in SOIL/OCL
	**********************************************************************/
	public boolean bemCriada()
	{
		//	DONE
		//	return ((((((((self.day.isDefined and (self.day > 0)) and (self.day <= 31)) and self.month.isDefined) and (self.month > 0)) and (self.month <= 12)) and self.year.isDefined) and (self.year >= 2000)) and (self.year <= 2500))
		
		return (this.day>0 && this.day<= 31 && this.month>0 && this.month<=12 && this.year > 1500 && this.year <=2500);
	}
	
	/**********************************************************************
	* User-defined operation specified in SOIL/OCL
	* @param day the day to set
	* @param month the month to set
	* @param year the year to set
	**********************************************************************/
//	public void init(int day, int month, int year)
//	{
//		//	TODO
//		//	self.day := day;
//		//	 self.month := month;
//		//	 self.year := year;
//	}
	
	/**********************************************************************
	* User-defined operation specified in SOIL/OCL
	* @param date the date to set
	**********************************************************************/
	public void initS(String date)
	{
		//	DONE
		//	self.year := date.substring(1,4).toInteger;
		//	 self.month := date.substring(6,7).toInteger;
		//	 self.day := date.substring(9,10).toInteger;
		StringBuilder yystring=new StringBuilder();
		yystring.append(date.charAt(0)+""+date.charAt(1)+""+date.charAt(2)+""+date.charAt(3)) ;
		
		StringBuilder mmstring=new StringBuilder();
		mmstring.append(date.charAt(4)+""+date.charAt(5)) ;
		
		StringBuilder ddstring=new StringBuilder();
		ddstring.append(date.charAt(6)+""+date.charAt(7)) ;
		
		this.year=Integer.parseInt(yystring.toString());
		this.month=Integer.parseInt(mmstring.toString());
		this.day=Integer.parseInt(ddstring.toString());

	}
	
	/**********************************************************************
	* User-defined operation specified in SOIL/OCL
	* @param t the t to set
	**********************************************************************/
	public boolean isAfter(CalendarDate t)
	{
		//	DONE
		//	return if (self.year = t.year) then if (self.month = t.month) then (self.day > t.day) else (self.month > t.month) endif else (self.year > t.year) endif
		return (this.year==t.year && this.month==t.month && this.day>t.day) || (this.month>t.month) || (this.year>t.year);
	}
	
	/**********************************************************************
	* User-defined operation specified in SOIL/OCL
	* @param t the t to set
	**********************************************************************/
	public boolean isBefore(CalendarDate t)
	{
		//	DONE
		//	return if (self.year = t.year) then if (self.month = t.month) then (self.day < t.day) else (self.month < t.month) endif else (self.year < t.year) endif
		return (this.year==t.year && this.month==t.month && this.day<t.day) || (this.month<t.month) || (this.year<t.year);
	}
	
	/**********************************************************************
	* User-defined operation specified in SOIL/OCL
	* @param x the x to set
	* @param y the y to set
	**********************************************************************/
	public boolean isDivisible(int x, int y)
	{
		//	DONE
		//	return (((x div y) * y) = x)
		return (x%y==0);
	}
	
	/**********************************************************************
	* User-defined operation specified in SOIL/OCL
	* @param t the t to set
	**********************************************************************/
	public boolean isEqual(CalendarDate t)
	{
		//	DONE
		//	return (((self.year = t.year) and (self.month = t.month)) and (self.day = t.day))
		return (this.year==t.year && this.month==t.month && this.day==t.day);
	}
	
	/**********************************************************************
	* User-defined operation specified in SOIL/OCL
	**********************************************************************/
	public boolean isLeap()
	{
		//	DONE
		//	return if (self.isDivisible(self.year, 400) or self.isDivisible(self.year, 4)) then true 
		//  else if self.isDivisible(self.year, 100) then false 
		//  else if self.isDivisible(self.year, 4) then true 
		//  else false endif endif endif
		if(this.isDivisible(this.year, 400) || this.isDivisible(this.year, 4)){
			return true;
		}else if(this.isDivisible(this.year, 100)){
			return false;
		}else if(this.isDivisible(this.year,4)){
			return true;
		}
		return false;
	}
	
	/**********************************************************************
	* User-defined operation specified in SOIL/OCL
	* @param date the date to set
	**********************************************************************/
	public CalendarDate stringToDate(String date)
	{
        Integer date_year = Integer.parseInt(date.substring(1,4));
        Integer date_month = Integer.parseInt(date.substring(5,6));
        Integer date_day = Integer.parseInt(date.substring(7,8));
        CalendarDate result=null;
        for(CalendarDate d:CalendarDate.allInstances){
                if(d.year==date_year&&d.month==date_month&&d.day==date_day){
                        result=d;
                }
        }
        
        if(result==null){
                result=new CalendarDate(date_day,date_month,date_year);
        }
        return result;

	}
	
	/**********************************************************************
	* User-defined operation specified in SOIL/OCL
	* @param t the t to set
	**********************************************************************/
	public int yearsSince(CalendarDate t)
	{
		//	DONE
		//	return if ((self.month < t.month) or ((self.month = t.month) and (self.day < t.day))) then ((self.year - t.year) - 1) else (self.year - t.year) endif
		if((this.month<t.month || this.month==t.month) && (this.day<t.day)){
			return (this.year-t.year)-1;
		}else{
			return this.year - t.year;
		}
	}
	
	/* (non-Javadoc)
	* @see java.lang.Object#toString()
	*/
	@Override
	/**********************************************************************
	* Object serializer
	**********************************************************************/
	public String toString()
	{
		return "CalendarDate [day=" + day + ", month=" + month + ", year=" + year + "]\n";
	}
	
}
